#include "StompedReality/Core/FileSystem.h"
#include "StompedReality/Core/IGame.h"
#include "StomperLib/Controls/FileTree.h"
#include <assert.h>
namespace StomperLib {
namespace Controls {
GWEN_CONTROL_CONSTRUCTOR( FileTree )
{
}
void FileTree::SetFilter( const StompedReality::Utility::FileFilter filter )
{
  this->m_Filter = filter;
}

void FileTree::Refresh( )
{
  assert( this->m_Game != NULL );
  assert( this->m_Game->getFileSystem( ) != NULL );
  assert( this->m_Filter != NULL );
  std::shared_ptr<StompedReality::Utility::FileInfoList> fList = this->m_Game->getFileSystem( )->findFiles(
      this->m_Filter );
  for (auto iter = fList->begin( ); iter != fList->end( ); ++iter)
  {
    this->AddFile( *iter );
  }
  ExpandAll( );
}

Gwen::Controls::TreeNode* FileTree::AddFile( StompedReality::Utility::FileInfo fileInfo )
{
  return this->AddFile( fileInfo.path, fileInfo.name );
}

Gwen::Controls::TreeNode* FileTree::AddFile( const Gwen::String path, const Gwen::String file )
{
  Gwen::String relativeFileName = path;
  relativeFileName.append( "/" );
  relativeFileName.append( file );

  auto fileNode = this->FindChild<Gwen::Controls::TreeNode>( relativeFileName, true );

  if (fileNode != NULL)
    return fileNode;

  auto prop = this->FindChild<Gwen::Controls::TreeNode>( path, true );
  if (prop == NULL)
  {
    prop = this->CreatePathNode( path );
  }

  fileNode = prop->AddNode( file );

  Gwen::String fullFileName;
  fullFileName.append( this->m_Game->getFileSystem( )->getBasePath( ));
  fullFileName.append( FILE_SEPARATORE_STR );
  fullFileName.append( relativeFileName );

  fileNode->SetName( relativeFileName );

  Gwen::Event::Information info;
  info.String = relativeFileName;

  onFileAdded.Call( this, info );

  fileNode->onSelectChange.Add( this, &FileTree::OnFileSelection );

  return fileNode;
}

Gwen::Controls::TreeNode* FileTree::CreatePathNode( const Gwen::String path )
{
  Gwen::Controls::TreeNode* prop = this->FindChild<Gwen::Controls::TreeNode>( path, true );
  if (prop == NULL)
  {
    int p = path.find_last_of( '/' );
    if (p == -1)
    {
      prop = this->AddNode( path );
      prop->SetShouldDrawBackground( true );
      prop->SetName( path );
      prop->SetSelectable( false );
    } else {
      Gwen::Controls::TreeNode* propPartial = this->CreatePathNode( path.substr( 0, p ));
      prop = propPartial->AddNode( path.substr( p+1, path.find_first_of( "/", p+1 ) - p ));
      prop->SetName( path.substr( 0, path.find_first_of( "/", p+1 )));
      prop->SetSelectable( false );
    }
  }
  return prop;
}

void FileTree::SetPath( const Gwen::String path )
{
  this->m_Path = path;
}

void FileTree::OnFileSelection( Gwen::Event::Info info )
{
  Gwen::Event::Information newInfo;
  newInfo.String = Gwen::TextObject( info.Control->GetName( ));
  this->onFileSelection.Call( this, newInfo );
}

void FileTree::NotifyNotSaved( std::string fileName )
{
  auto node = this->FindChild<Gwen::Controls::TreeNode>( fileName, true );

  if (node == NULL)
    return;

  Gwen::String text = node->GetText( ).Get( );
  char x = text[text.length( )-1];
  if (x != '*')
  {
    text.append( "*" );
    node->SetText( text );
  }
}

void FileTree::NotifySaved( std::string fileName )
{
  auto node = this->FindChild<Gwen::Controls::TreeNode>( fileName, true );

  if (node == NULL)
    return;

  Gwen::String text = node->GetText( ).Get( ).substr( 0, node->GetText( ).length( )-1 );

  node->SetText( text );
}

}
}